package com.lz.stream;

import org.junit.Before;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Classname: com.lz.stream.SreamTest
 * @Description: {@link Stream} Api使用
 * <p>
 *     Stream三大特性 ： 1.stream不存储数据
 *                      2.stream不改变源数据
 *                      3.stream的延迟执行特性
 * </p>
 * @Date: 2019/1/7 13:58
 * @Created by: li
 * @Version: V1.0
 */
public class SreamTest {
    List<Student> stuList = null;
    List<String> wordList = null;

    @Before
    public void init() {
        Random random = new Random();
        stuList = new ArrayList<Student>() {
            {
                for (int i = 0; i < 100; i++) {
                    add(new Student("student" + i, random.nextInt(50) + 50));
                }
            }
        };
    }

    /**
     * @title:
     * @param
     * @return void
     * @description:
     *
     * @created by: li
     * @date: 2019/1/7 14:20
     */
    @Test
    public void test01() {
        Stream<List<Integer>> inputStream = Stream.of(
                Arrays.asList(1),
                Arrays.asList(2, 3),
                Arrays.asList(4, 5, 6)
        );
        Stream<Integer> outputStream = inputStream.
                flatMap((childList) -> childList.stream());
        System.out.println(Arrays.toString(outputStream.toArray()));
        return;

    }

    /**
     *
     1列出班上超过85分的学生姓名，并按照分数降序输出用户名字
     */
    @Test
    public void test03() {
        List<Student> list = stuList.parallelStream()
                .filter(x -> x.getScore() < 60).sorted(Comparator.comparing(Student::getScore).reversed()).collect(Collectors.toList());

        System.out.println(list);
        Stream<Student> sorted = stuList.parallelStream()
                .filter(x -> x.getScore() < 60).sorted(Comparator.comparing(Student::getScore).reversed());
        // 重复消费满足1 不储存数据  2 延迟操作 Stream 此处没有排序
        sorted.forEach(System.out::println);
        sorted.forEach(System.out::println);


        List<String> studentList = stuList.stream()
                .filter(x -> x.getScore() > 85)
                .sorted(Comparator.comparing(Student::getScore).reversed())
                .map(Student::getName)
                .collect(Collectors.toList());
        System.out.println(studentList);
        return;
    }

    /**
     * 保留偶数
     */
    @Test
    public void test02() {
        Integer[] sixNums = {1, 2, 3, 4, 5, 6};
        Integer[] evens =
                Stream.of(sixNums).filter(n -> n % 2 == 0).toArray(Integer[]::new);
        System.out.println(Arrays.toString(evens));
    }


    /**
     * Stream 的聚合、消费或收集操作只能进行一次，再次操作会报错
     */
    @Test
    public void test04() {
        Stream<String> stream = Stream.generate(() -> "user").limit(20);
        stream.forEach(System.out::println);
        stream.forEach(System.out::println);
    }

    /**
     * 延迟执行特性，会产生干扰 stram.forEach执行4次，抛出4次空指针，remove()
     * nullPointException
     */
    @Before
    public void test05() {
        wordList = new ArrayList<String>() {
            {
                add("a");
                add("b");
                add("c");
                add("d");
                add("e");
                add("f");
            }
        };
        Stream<String> words1 = wordList.stream();
        AtomicInteger atomicInteger = new AtomicInteger(0);
        words1.forEach(s -> {
            System.out.println("s->" + s);
            if (s.length() < 4) {
                System.out.println("select->" + s);
                wordList.remove(s);
                System.out.println(wordList);
            }
            System.out.println(atomicInteger.incrementAndGet());
        });
    }

}


class Student {
    private String name;
    private Integer score;

    public Student(String name, Integer score) {
        this.name = name;
        this.score = score;
    }
    //-----getters and setters-----

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getScore() {
        return score;
    }

    public void setScore(Integer score) {
        this.score = score;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", score=" + score +
                '}';
    }
}
